/**
 * Matrix Framework 权限管理服务
 * 集成ABP vNext框架的权限管理功能
 */

import apiClient, { type AbpResponse, type AbpQueryResult } from '@/utils/api'
import MockService, { useMockService } from './mock.service'
import type {
  Permission,
  Role,
  CreateRoleRequest,
  UpdateRoleRequest,
  RoleQueryParams,
  RoleQueryResult,
  PermissionDefinition,
  PermissionProvider,
  PermissionCheckRequest,
  PermissionCheckResult,
  UserPermissionAssignment,
  RolePermissionAssignment,
  PermissionPolicy,
  PermissionTemplate,
  PermissionAuditLog,
  PermissionUsageStatistics,
  PermissionEvaluationResult,
  BulkPermissionOperationRequest,
  PermissionExportRequest,
  PermissionImportRequest
} from '@/types/permission'
import type { AbpResponse } from '@/types/abp'
import abpService from './abp.service'

class PermissionService {
  private static instance: PermissionService
  private readonly permissionApiBasePath = '/api/abp/permissions'
  private readonly roleApiBasePath = '/api/identity/roles'

  private constructor() {}

  /**
   * 获取单例实例
   */
  static getInstance(): PermissionService {
    if (!PermissionService.instance) {
      PermissionService.instance = new PermissionService()
    }
    return PermissionService.instance
  }

  // ==================== 权限管理 ====================

  /**
   * 获取所有权限
   */
  async getAllPermissions(): Promise<Permission[]> {
    try {
      // 如果启用Mock服务，使用Mock数据
      if (useMockService) {
        return await MockService.getPermissionList()
      }

      const response = await apiClient.get<Permission[]>(
        `${this.permissionApiBasePath}`
      )

      return response
    } catch (error) {
      console.error('获取权限列表失败:', error)
      throw error
    }
  }

  /**
   * 获取权限提供者
   */
  async getPermissionProviders(): Promise<PermissionProvider[]> {
    try {
      const response = await axios.get<AbpResponse<PermissionProvider[]>>(
        `${this.permissionApiBasePath}/providers`
      )

      return response.data.result
    } catch (error) {
      console.error('获取权限提供者失败:', error)
      throw error
    }
  }

  /**
   * 检查权限
   */
  async checkPermissions(request: PermissionCheckRequest): Promise<PermissionCheckResult> {
    try {
      const response = await axios.post<AbpResponse<PermissionCheckResult>>(
        `${this.permissionApiBasePath}/check`,
        request
      )

      return response.data.result
    } catch (error) {
      console.error('检查权限失败:', error)
      throw error
    }
  }

  /**
   * 获取用户权限
   */
  async getUserPermissions(userId: string): Promise<Permission[]> {
    try {
      const response = await axios.get<AbpResponse<Permission[]>>(
        `${this.permissionApiBasePath}/user/${userId}`
      )

      return response.data.result
    } catch (error) {
      console.error(`获取用户权限失败 [${userId}]:`, error)
      throw error
    }
  }

  /**
   * 获取角色权限
   */
  async getRolePermissions(roleId: string): Promise<Permission[]> {
    try {
      const response = await axios.get<AbpResponse<Permission[]>>(
        `${this.permissionApiBasePath}/role/${roleId}`
      )

      return response.data.result
    } catch (error) {
      console.error(`获取角色权限失败 [${roleId}]:`, error)
      throw error
    }
  }

  /**
   * 分配用户权限
   */
  async assignUserPermissions(userId: string, assignments: UserPermissionAssignment[]): Promise<void> {
    try {
      if (!abpService.hasPermission('AbpIdentity.Users.ManagePermissions')) {
        throw new Error('没有管理用户权限')
      }

      await axios.post(`${this.permissionApiBasePath}/user/${userId}/assign`, {
        permissions: assignments
      })

      abpService.log('Information', `用户权限分配成功`, {
        userId,
        operation: 'AssignUserPermissions',
        permissionCount: assignments.length
      })
    } catch (error) {
      console.error(`分配用户权限失败 [${userId}]:`, error)
      throw error
    }
  }

  /**
   * 分配角色权限
   */
  async assignRolePermissions(roleId: string, assignments: RolePermissionAssignment[]): Promise<void> {
    try {
      if (!abpService.hasPermission('AbpIdentity.Roles.ManagePermissions')) {
        throw new Error('没有管理角色权限')
      }

      await axios.post(`${this.permissionApiBasePath}/role/${roleId}/assign`, {
        permissions: assignments
      })

      abpService.log('Information', `角色权限分配成功`, {
        roleId,
        operation: 'AssignRolePermissions',
        permissionCount: assignments.length
      })
    } catch (error) {
      console.error(`分配角色权限失败 [${roleId}]:`, error)
      throw error
    }
  }

  // ==================== 角色管理 ====================

  /**
   * 获取角色列表
   */
  async getRoles(params: RoleQueryParams = {}): Promise<RoleQueryResult> {
    try {
      // 如果启用Mock服务，使用Mock数据
      if (useMockService) {
        return await MockService.getRoleList(params)
      }

      if (!abpService.hasPermission('AbpIdentity.Roles')) {
        throw new Error('没有角色管理权限')
      }

      const response = await apiClient.get<RoleQueryResult>(
        this.roleApiBasePath,
        { params }
      )

      return response
    } catch (error) {
      console.error('获取角色列表失败:', error)
      throw error
    }
  }

  /**
   * 根据ID获取角色详情
   */
  async getRoleById(id: string): Promise<Role> {
    try {
      if (!abpService.hasPermission('AbpIdentity.Roles')) {
        throw new Error('没有角色管理权限')
      }

      const response = await axios.get<AbpResponse<Role>>(
        `${this.roleApiBasePath}/${id}`
      )

      return response.data.result
    } catch (error) {
      console.error(`获取角色详情失败 [${id}]:`, error)
      throw error
    }
  }

  /**
   * 创建角色
   */
  async createRole(request: CreateRoleRequest): Promise<Role> {
    try {
      if (!abpService.hasPermission('AbpIdentity.Roles.Create')) {
        throw new Error('没有创建角色权限')
      }

      const response = await axios.post<AbpResponse<Role>>(
        this.roleApiBasePath,
        request
      )

      abpService.log('Information', `角色 "${request.name}" 创建成功`, {
        roleName: request.name,
        operation: 'CreateRole'
      })

      return response.data.result
    } catch (error) {
      console.error('创建角色失败:', error)
      throw error
    }
  }

  /**
   * 更新角色
   */
  async updateRole(id: string, request: UpdateRoleRequest): Promise<Role> {
    try {
      if (!abpService.hasPermission('AbpIdentity.Roles.Update')) {
        throw new Error('没有更新角色权限')
      }

      const response = await axios.put<AbpResponse<Role>>(
        `${this.roleApiBasePath}/${id}`,
        request
      )

      abpService.log('Information', `角色 "${request.name}" 更新成功`, {
        roleId: id,
        operation: 'UpdateRole'
      })

      return response.data.result
    } catch (error) {
      console.error(`更新角色失败 [${id}]:`, error)
      throw error
    }
  }

  /**
   * 删除角色
   */
  async deleteRole(id: string): Promise<void> {
    try {
      if (!abpService.hasPermission('AbpIdentity.Roles.Delete')) {
        throw new Error('没有删除角色权限')
      }

      await axios.delete(`${this.roleApiBasePath}/${id}`)

      abpService.log('Warning', `角色删除成功`, {
        roleId: id,
        operation: 'DeleteRole'
      })
    } catch (error) {
      console.error(`删除角色失败 [${id}]:`, error)
      throw error
    }
  }

  // ==================== 权限策略管理 ====================

  /**
   * 获取权限策略
   */
  async getPermissionPolicies(): Promise<PermissionPolicy[]> {
    try {
      if (!abpService.hasPermission('AbpPermissions.ManagePolicies')) {
        throw new Error('没有管理权限策略权限')
      }

      const response = await axios.get<AbpResponse<PermissionPolicy[]>>(
        `${this.permissionApiBasePath}/policies`
      )

      return response.data.result
    } catch (error) {
      console.error('获取权限策略失败:', error)
      throw error
    }
  }

  /**
   * 创建权限策略
   */
  async createPermissionPolicy(policy: PermissionPolicy): Promise<PermissionPolicy> {
    try {
      if (!abpService.hasPermission('AbpPermissions.ManagePolicies')) {
        throw new Error('没有管理权限策略权限')
      }

      const response = await axios.post<AbpResponse<PermissionPolicy>>(
        `${this.permissionApiBasePath}/policies`,
        policy
      )

      abpService.log('Information', `权限策略 "${policy.name}" 创建成功`, {
        policyName: policy.name,
        operation: 'CreatePermissionPolicy'
      })

      return response.data.result
    } catch (error) {
      console.error('创建权限策略失败:', error)
      throw error
    }
  }

  /**
   * 更新权限策略
   */
  async updatePermissionPolicy(id: string, policy: PermissionPolicy): Promise<PermissionPolicy> {
    try {
      if (!abpService.hasPermission('AbpPermissions.ManagePolicies')) {
        throw new Error('没有管理权限策略权限')
      }

      const response = await axios.put<AbpResponse<PermissionPolicy>>(
        `${this.permissionApiBasePath}/policies/${id}`,
        policy
      )

      return response.data.result
    } catch (error) {
      console.error(`更新权限策略失败 [${id}]:`, error)
      throw error
    }
  }

  /**
   * 删除权限策略
   */
  async deletePermissionPolicy(id: string): Promise<void> {
    try {
      if (!abpService.hasPermission('AbpPermissions.ManagePolicies')) {
        throw new Error('没有管理权限策略权限')
      }

      await axios.delete(`${this.permissionApiBasePath}/policies/${id}`)

      abpService.log('Warning', `权限策略删除成功`, {
        policyId: id,
        operation: 'DeletePermissionPolicy'
      })
    } catch (error) {
      console.error(`删除权限策略失败 [${id}]:`, error)
      throw error
    }
  }

  // ==================== 权限模板管理 ====================

  /**
   * 获取权限模板
   */
  async getPermissionTemplates(): Promise<PermissionTemplate[]> {
    try {
      if (!abpService.hasPermission('AbpPermissions.ManageTemplates')) {
        throw new Error('没有管理权限模板权限')
      }

      const response = await axios.get<AbpResponse<PermissionTemplate[]>>(
        `${this.permissionApiBasePath}/templates`
      )

      return response.data.result
    } catch (error) {
      console.error('获取权限模板失败:', error)
      throw error
    }
  }

  /**
   * 创建权限模板
   */
  async createPermissionTemplate(template: Omit<PermissionTemplate, 'id' | 'creationTime'>): Promise<PermissionTemplate> {
    try {
      if (!abpService.hasPermission('AbpPermissions.ManageTemplates')) {
        throw new Error('没有管理权限模板权限')
      }

      const response = await axios.post<AbpResponse<PermissionTemplate>>(
        `${this.permissionApiBasePath}/templates`,
        template
      )

      abpService.log('Information', `权限模板 "${template.name}" 创建成功`, {
        templateName: template.name,
        operation: 'CreatePermissionTemplate'
      })

      return response.data.result
    } catch (error) {
      console.error('创建权限模板失败:', error)
      throw error
    }
  }

  /**
   * 应用权限模板
   */
  async applyPermissionTemplate(templateId: string, targetId: string, targetType: 'User' | 'Role' | 'Tenant'): Promise<void> {
    try {
      if (!abpService.hasPermission('AbpPermissions.ManageTemplates')) {
        throw new Error('没有管理权限模板权限')
      }

      await axios.post(`${this.permissionApiBasePath}/templates/${templateId}/apply`, {
        targetId,
        targetType
      })

      abpService.log('Information', `权限模板应用成功`, {
        templateId,
        targetId,
        targetType,
        operation: 'ApplyPermissionTemplate'
      })
    } catch (error) {
      console.error(`应用权限模板失败 [${templateId}]:`, error)
      throw error
    }
  }

  // ==================== 权限审计和统计 ====================

  /**
   * 获取权限审计日志
   */
  async getPermissionAuditLogs(params: {
    userId?: string
    permissionName?: string
    operation?: string
    startTime?: string
    endTime?: string
    skipCount?: number
    maxResultCount?: number
  } = {}): Promise<{ items: PermissionAuditLog[]; totalCount: number }> {
    try {
      if (!abpService.hasPermission('AbpPermissions.ViewAuditLogs')) {
        throw new Error('没有查看审计日志权限')
      }

      const response = await axios.get<AbpResponse<{ items: PermissionAuditLog[]; totalCount: number }>>(
        `${this.permissionApiBasePath}/audit-logs`,
        { params }
      )

      return response.data.result
    } catch (error) {
      console.error('获取权限审计日志失败:', error)
      throw error
    }
  }

  /**
   * 获取权限使用统计
   */
  async getPermissionUsageStatistics(params: {
    permissionName?: string
    startTime?: string
    endTime?: string
    groupBy?: 'Permission' | 'User' | 'Role' | 'Day' | 'Week' | 'Month'
  } = {}): Promise<PermissionUsageStatistics[]> {
    try {
      if (!abpService.hasPermission('AbpPermissions.ViewStatistics')) {
        throw new Error('没有查看统计权限')
      }

      const response = await axios.get<AbpResponse<PermissionUsageStatistics[]>>(
        `${this.permissionApiBasePath}/usage-statistics`,
        { params }
      )

      return response.data.result
    } catch (error) {
      console.error('获取权限使用统计失败:', error)
      throw error
    }
  }

  // ==================== 权限评估 ====================

  /**
   * 评估权限
   */
  async evaluatePermission(request: {
    permissionName: string
    userId?: string
    tenantId?: string
    context?: Record<string, any>
  }): Promise<PermissionEvaluationResult> {
    try {
      const response = await axios.post<AbpResponse<PermissionEvaluationResult>>(
        `${this.permissionApiBasePath}/evaluate`,
        request
      )

      return response.data.result
    } catch (error) {
      console.error('评估权限失败:', error)
      throw error
    }
  }

  /**
   * 批量评估权限
   */
  async evaluatePermissions(request: {
    permissionNames: string[]
    userId?: string
    tenantId?: string
    context?: Record<string, any>
  }): Promise<PermissionEvaluationResult[]> {
    try {
      const response = await axios.post<AbpResponse<PermissionEvaluationResult[]>>(
        `${this.permissionApiBasePath}/evaluate-batch`,
        request
      )

      return response.data.result
    } catch (error) {
      console.error('批量评估权限失败:', error)
      throw error
    }
  }

  // ==================== 权限缓存管理 ====================

  /**
   * 清除权限缓存
   */
  async clearPermissionCache(params: {
    userId?: string
    roleId?: string
    tenantId?: string
    permissionName?: string
  } = {}): Promise<void> {
    try {
      if (!abpService.hasPermission('AbpPermissions.ManageCache')) {
        throw new Error('没有管理权限缓存权限')
      }

      await axios.post(`${this.permissionApiBasePath}/cache/clear`, params)

      abpService.log('Information', `权限缓存清除成功`, {
        ...params,
        operation: 'ClearPermissionCache'
      })
    } catch (error) {
      console.error('清除权限缓存失败:', error)
      throw error
    }
  }

  /**
   * 刷新权限缓存
   */
  async refreshPermissionCache(params: {
    userId?: string
    roleId?: string
    tenantId?: string
  } = {}): Promise<void> {
    try {
      if (!abpService.hasPermission('AbpPermissions.ManageCache')) {
        throw new Error('没有管理权限缓存权限')
      }

      await axios.post(`${this.permissionApiBasePath}/cache/refresh`, params)

      abpService.log('Information', `权限缓存刷新成功`, {
        ...params,
        operation: 'RefreshPermissionCache'
      })
    } catch (error) {
      console.error('刷新权限缓存失败:', error)
      throw error
    }
  }

  // ==================== 批量操作 ====================

  /**
   * 批量权限操作
   */
  async bulkPermissionOperation(request: BulkPermissionOperationRequest): Promise<void> {
    try {
      if (!abpService.hasPermission('AbpPermissions.BulkOperations')) {
        throw new Error('没有批量操作权限')
      }

      await axios.post(`${this.permissionApiBasePath}/bulk-operation`, request)

      abpService.log('Information', `批量权限操作成功`, {
        operation: request.operation,
        target: request.target,
        targetCount: request.targetIds.length,
        permissionCount: request.permissions.length
      })
    } catch (error) {
      console.error('批量权限操作失败:', error)
      throw error
    }
  }

  // ==================== 导入导出 ====================

  /**
   * 导出权限数据
   */
  async exportPermissions(request: PermissionExportRequest): Promise<Blob> {
    try {
      if (!abpService.hasPermission('AbpPermissions.Export')) {
        throw new Error('没有导出权限权限')
      }

      const response = await axios.post(
        `${this.permissionApiBasePath}/export`,
        request,
        {
          responseType: 'blob'
        }
      )

      abpService.log('Information', `权限数据导出完成`, {
        format: request.format,
        operation: 'ExportPermissions'
      })

      return response.data
    } catch (error) {
      console.error('导出权限数据失败:', error)
      throw error
    }
  }

  /**
   * 导入权限数据
   */
  async importPermissions(request: PermissionImportRequest): Promise<{ successCount: number; failureCount: number }> {
    try {
      if (!abpService.hasPermission('AbpPermissions.Import')) {
        throw new Error('没有导入权限权限')
      }

      const formData = new FormData()
      formData.append('file', request.file)
      formData.append('overwriteExisting', request.overwriteExisting.toString())
      formData.append('importMode', request.importMode)
      formData.append('validateOnly', request.validateOnly.toString())

      if (request.tenantId) {
        formData.append('tenantId', request.tenantId)
      }

      const response = await axios.post<AbpResponse<{ successCount: number; failureCount: number }>>(
        `${this.permissionApiBasePath}/import`,
        formData,
        {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        }
      )

      abpService.log('Information', `权限数据导入完成`, {
        fileName: request.file.name,
        result: response.data.result,
        operation: 'ImportPermissions'
      })

      return response.data.result
    } catch (error) {
      console.error('导入权限数据失败:', error)
      throw error
    }
  }

  // ==================== 权限验证辅助方法 ====================

  /**
   * 检查当前用户是否有指定权限
   */
  hasPermission(permissionName: string): boolean {
    return abpService.hasPermission(permissionName)
  }

  /**
   * 检查当前用户是否有任一权限
   */
  hasAnyPermission(permissionNames: string[]): boolean {
    return permissionNames.some(name => abpService.hasPermission(name))
  }

  /**
   * 检查当前用户是否有所有权限
   */
  hasAllPermissions(permissionNames: string[]): boolean {
    return permissionNames.every(name => abpService.hasPermission(name))
  }

  /**
   * 获取当前用户的所有权限
   */
  getCurrentUserPermissions(): string[] {
    return Object.keys(abpService.auth.grantedPolicies).filter(
      key => abpService.auth.grantedPolicies[key]
    )
  }
}

// 创建单例实例
const permissionService = PermissionService.getInstance()

export default permissionService
export { PermissionService }
export type {
  Permission,
  Role,
  CreateRoleRequest,
  UpdateRoleRequest,
  RoleQueryParams,
  RoleQueryResult,
  PermissionCheckRequest,
  PermissionCheckResult,
  PermissionEvaluationResult,
  BulkPermissionOperationRequest
}